package heap

import "lesson01/classfile"

type MethodRef struct {
	MemberRef
	method *Method
}

func newMethodRef(cp *ConstantPool, method *classfile.ConstantMethodrefInfo) *MethodRef {
	methodRef := &MethodRef{}
	methodRef.cp = cp
	methodRef.copyMemberRefInfo(&method.ConstantMemberrefInfo)
	return methodRef
}

// ResolveMethod 解析方法
func (e *MethodRef) ResolveMethod() *Method {
	if e.method == nil {
		e.resolvedMethodRef()
	}
	return e.method
}

func (e *MethodRef) resolvedMethodRef() {
	clazz := e.cp.class
	class := e.ResolvedClass()
	if class.IsInterface() {
		panic("java.lang.IncompatibleClassChangeError")
	}
	method := lookupMethod(class, e.name, e.descriptor)
	if method == nil {
		panic("java.lang.NoSuchMethodError")
	}
	if !method.isAccessibleTo(clazz) {
		panic("java.lang.IllegalAccessError")
	}
	e.method = method
}

func lookupMethod(class *Class, name string, descriptor string) *Method {
	method := LookupMethodInClass(class, name, descriptor)
	if method == nil {
		method = lookupMethodInInterfaces(class.interfaces, name, descriptor)
	}

	return method
}
